﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Trippy.CollidableGameComponents;
using Trippy.CollidableGameComponents.Events;
using Trippy.Abilities;
using Trippy.CollidableGameComponents.Agents;


namespace Trippy.UI_Overlay
{
    class InGamePause : TrippyState
    {
        List<MenuWindow> menuList = new List<MenuWindow>();
        public new TrippyGame Game { get; protected set; }
        MenuWindow menuMain;
        MenuWindow activeMenu;
        bool menusRunning = true;
        MenuWindow closeGame;
        MenuWindow menuNewGame;
        MenuWindow loadState;
        MenuWindow saveState;
        MenuWindow resumeGame;
        MenuWindow menuConfig;
        Levels.Level currentGame;
        MenuWindow leftConfig;
        MenuWindow rightConfig;
        MenuWindow jumpConfig;
        MenuWindow actionConfig;
        MenuWindow inGameMenuConfig;
        KeyboardState CurKeyState;
        KeyboardState PrevKeyState;
        private SpriteBatch spriteBatch;
        protected static int savedScore = 0, savedLives = TrippyConstants.Agent.Hero.Lives;
        protected static Ability savedCurrentAbility = null, savedPreviousAbility = null;
        public static Levels.Level savedLevel;
        protected static List<CollidableGameComponent> savedPowerList = new List<CollidableGameComponent>();
        public static GameComponentCollection saveList = new GameComponentCollection();

        public InGamePause(TrippyGame game, Levels.Level current)
            : base(game)
        {
            Game = game;
            currentGame = current;
            spriteBatch = new SpriteBatch(Game.GraphicsDevice);
        }
        protected override void LoadContent()
        {
            SpriteFont menuFont = Game.Content.Load<SpriteFont>("Fonts/UI");
            Texture2D background = Game.Content.Load<Texture2D>("Background/abstract_bkg");
            MediaPlayer.Play(Game.menuSong);
            //Creating menuItems and adding to the menuList
            menuMain = new MenuWindow(menuFont, "Paused", background);
            menuNewGame = new MenuWindow(null, null, null);
            saveState = new MenuWindow(null, null, null);
            loadState = new MenuWindow(null, null, null);
            resumeGame = new MenuWindow(null, null, null);
            menuConfig = new MenuWindow(null, null, null);
            leftConfig = new MenuWindow(null, null, null);
            rightConfig = new MenuWindow(null, null, null);
            jumpConfig = new MenuWindow(null, null, null);
            actionConfig = new MenuWindow(null, null, null);
            inGameMenuConfig = new MenuWindow(null, null, null);
            closeGame = new MenuWindow(null, null, null);
            menuConfig = new MenuWindow(menuFont, "Key Configuration", background);
            activeMenu = menuMain;
            menuList.Add(menuMain);
            menuList.Add(menuNewGame);
            menuList.Add(menuConfig);

            menuMain.AddMenuItem("Resume", resumeGame);
            menuMain.AddMenuItem("Save State", saveState);
            menuMain.AddMenuItem("Load State", loadState);
            menuMain.AddMenuItem("Reset", menuNewGame);
            menuMain.AddMenuItem("Configuration", menuConfig);
            menuConfig.AddMenuItem("Left               Key: " + Game.left.ToString(), leftConfig);
            menuConfig.AddMenuItem("Right              Key: " + Game.right.ToString(), rightConfig);
            menuConfig.AddMenuItem("Up/Jump            Key: " + Game.jump.ToString(), jumpConfig);
            menuConfig.AddMenuItem("Action             Key: " + Game.action.ToString(), actionConfig);
            menuConfig.AddMenuItem("Menu               Key: " + Game.menu.ToString(), inGameMenuConfig);
            menuConfig.AddMenuItem("Back", menuMain);
            menuMain.AddMenuItem("Quit", closeGame);

            menuMain.WakeUp();
        }

        public override void Update(GameTime gameTime)
        {
            CurKeyState = Keyboard.GetState();

            if (menusRunning)
            {
                foreach (MenuWindow currentMenu in menuList)
                    currentMenu.Update(gameTime.ElapsedGameTime.TotalMilliseconds);
                MenuInput(CurKeyState);
            }
            else { }
            base.Update(gameTime);
            PrevKeyState = CurKeyState;
        }

        public override void Draw(GameTime gametime)
        {
            spriteBatch.Begin();
            foreach (MenuWindow currentMenu in menuList)
                currentMenu.Draw(spriteBatch);
            spriteBatch.End();
        }            

        private void MenuInput(KeyboardState currentKeybState)
        {
            MenuWindow newActive = activeMenu.ProcessInput(PrevKeyState, currentKeybState);

            //if (newActive.windowState != MenuWindow.WindowState.Starting)
            //{
                if (newActive == resumeGame)
                {
                    Game.Components.Clear();
                    currentGame.updateKeys();
                    Game.Components.Add(currentGame);
                    menusRunning = false;
                }
                else if (newActive == saveState)
                {
                    Vector2 savePosition = new Vector2(currentGame.Hero.Position.X, currentGame.Hero.Position.Y);
                    Game.spawnPoint = savePosition;
                    Game.Components.Clear();
                    currentGame.updateKeys();
                    Game.Components.Add(currentGame);
                    saveList.Clear();
                    foreach (GameComponent x in currentGame.Objects)
                        saveList.Add(x);
                    foreach (CollidableGameComponent x in currentGame.powerList)
                        savedPowerList.Add(x);
                    menusRunning = false;
                    savedLives = Hero.Lives;
                    savedScore = Hero.Score;
                    savedCurrentAbility = currentGame.Hero.CurrentAbility;
                    savedPreviousAbility = Hero.PreviousAbility;
                    savedLevel = currentGame;
                }
                else if (newActive == loadState)
                {
                    Game.Components.Clear();
                    currentGame.updateKeys();
                    currentGame = savedLevel;
                    Game.currentState = savedLevel;
                    Game.Components.Add(currentGame);
                    Vector2 tempPosition = new Vector2(currentGame.SpawnPoint.X, currentGame.SpawnPoint.Y);
                    currentGame.SpawnPoint = Game.spawnPoint;
                    currentGame.Objects.Clear();
                    currentGame.powerList.Clear();
                    foreach (GameComponent element in saveList)
                    {
                        currentGame.Add(element);
                        if(element is CollidableGameComponent)
                          (element as CollidableGameComponent).Restore();
                    }
                    foreach (CollidableGameComponent element in savedPowerList)
                        currentGame.powerList.Add(element);
                    Hero.Lives = savedLives;
                    Hero.Score = savedScore;
                    currentGame.Hero.Restore(); //reset hero's state
                    currentGame.Hero.CurrentAbility = savedCurrentAbility;
                    Hero.PreviousAbility = savedPreviousAbility;
                    if (currentGame.Hero.CurrentAbility != null)
                    {
                        currentGame.Hero.CurrentAbility.OnAdd();
                    }
                    currentGame.Spawn(currentGame.Hero);
                    currentGame.SpawnPoint = tempPosition;
                    menusRunning = false;
                }
                else if (newActive == menuNewGame)
                {
                    menusRunning = false;
                    Hero.Lives = 10;
                    Hero.Score = 0;
                    currentGame.Hero.CurrentAbility = null;
                    Hero.PreviousAbility = null;
                    var firstLevel = new Levels.FirstLevel(Game, null); // if no hero is passed as a parameter, one is automatically created
                    currentGame = firstLevel;
                    Game.currentState = firstLevel;
                    Game.Components.Clear();
                    Game.Components.Add(firstLevel);
                }
                else if (newActive == leftConfig && currentKeybState.GetPressedKeys().Length > 0)
                {
                    if (currentKeybState.GetPressedKeys()[0] == Keys.Enter)
                    {
                        menuConfig.active = true;
                        activeMenu.Active();
                        newActive = leftConfig;
                    }
                    if (currentKeybState.GetPressedKeys()[0] != Keys.Enter)
                    {
                        Keys pressedKey = currentKeybState.GetPressedKeys()[0];
                        Game.left = pressedKey;
                        menuConfig.itemList[0].itemText = "Left               Key: " + Game.left.ToString();
                        menuConfig.active = false;
                        activeMenu.Active();
                        activeMenu = newActive = menuConfig;
                    }
                }
                else if (newActive == rightConfig && currentKeybState.GetPressedKeys().Length > 0)
                {
                    if (currentKeybState.GetPressedKeys()[0] == Keys.Enter)
                    {
                        menuConfig.active = true;
                        activeMenu.Active();
                        newActive = rightConfig;
                    }
                    if (currentKeybState.GetPressedKeys()[0] != Keys.Enter)
                    {
                        Keys pressedKey = currentKeybState.GetPressedKeys()[0];
                        Game.right = pressedKey;
                        menuConfig.itemList[1].itemText = "Right              Key: " + Game.right.ToString();
                        menuConfig.active = false;
                        activeMenu.Active();
                        activeMenu = newActive = menuConfig;
                    }
                }
                else if (newActive == jumpConfig && currentKeybState.GetPressedKeys().Length > 0)
                {
                    if (currentKeybState.GetPressedKeys()[0] == Keys.Enter)
                    {
                        menuConfig.active = true;
                        activeMenu.Active();
                        newActive = jumpConfig;
                    }
                    if (currentKeybState.GetPressedKeys()[0] != Keys.Enter)
                    {
                        Keys pressedKey = currentKeybState.GetPressedKeys()[0];
                        Game.jump = pressedKey;
                        menuConfig.itemList[2].itemText = "Up/Jump            Key: " + Game.jump.ToString();
                        menuConfig.active = false;
                        activeMenu.Active();
                        activeMenu = newActive = menuConfig;
                    }
                }
                else if (newActive == actionConfig && currentKeybState.GetPressedKeys().Length > 0)
                {
                    if (currentKeybState.GetPressedKeys()[0] == Keys.Enter)
                    {
                        menuConfig.active = true;
                        activeMenu.Active();
                        newActive = actionConfig;
                    }
                    if (currentKeybState.GetPressedKeys()[0] != Keys.Enter)
                    {
                        Keys pressedKey = currentKeybState.GetPressedKeys()[0];
                        Game.action = pressedKey;
                        menuConfig.itemList[3].itemText = "Action             Key: " + Game.action.ToString();
                        menuConfig.active = false;
                        activeMenu.Active();
                        activeMenu = newActive = menuConfig;
                    }
                }
                else if (newActive == inGameMenuConfig && currentKeybState.GetPressedKeys().Length > 0)
                {
                    if (currentKeybState.GetPressedKeys()[0] == Keys.Enter)
                    {
                        menuConfig.active = true;
                        activeMenu.Active();
                        newActive = inGameMenuConfig;
                    }
                    if (currentKeybState.GetPressedKeys()[0] != Keys.Enter)
                    {
                        Keys pressedKey = currentKeybState.GetPressedKeys()[0];
                        Game.menu = pressedKey;
                        menuConfig.itemList[4].itemText = "Menu               Key: " + Game.menu.ToString();
                        menuConfig.active = false;
                        activeMenu.Active();
                        activeMenu = newActive = menuConfig;
                    }
                }
                else if (newActive == closeGame)
                    Game.Exit();
                else if (newActive == null)
                    Game.Exit();
                else if (newActive != activeMenu)
                    newActive.WakeUp();
                activeMenu = newActive;
            }
       // }
    }
}
